#ifndef _VL_RTSP_CONNECTION__H_
#define _VL_RTSP_CONNECTION__H_

#include "defs.h"
#include "rtsp_parser.h"
#include "media_session.h"
#include "media_dispatcher.h"
#include "utils/tcpsocket.h"
#include "utils/queue_thread.h"
#include "utils/runnable_thread.h"

namespace VLRTSP {

/**
 * @Author: CimZzz
 * @Date: 2022-01-13 11:16:38
 * 
 * 声明 RTSPContext
 */
class RTSPContext;

/**
 * @Author: CimZzz
 * @Date: 2022-01-11 15:42:03
 * 
 * RTSP 链接
 */
class RTSPConnection {

public:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 09:29:49
	 * 
	 * 链接关闭回调函数
	 * @param 1 链接 Id
	 * @param 2 关闭消息指针，如果正常关闭该值为 nullptr
	 */
	using CloseCallback = std::function<void(uint32_t, std::shared_ptr<std::string>)>;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 15:42:12
	 * 
	 * 构造函数
	 * @param connectionId 链接 Id
	 * @param context RTSP 上下文
	 * @param socket 套接字
	 * @param closeCallback 链接关闭回调函数
	 */
	explicit RTSPConnection(
		uint32_t connectionId,
		RTSPContext* context,
		const std::shared_ptr<TCPSocket>& socket
	);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 15:52:00
	 * 
	 * 析构函数
	 */
	~RTSPConnection();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 19:23:31
	 * 
	 * 添加链接关闭回调函数
	 * @param closeCallback 链接关闭回调
	 * @return 如果添加回调成功返回 true
	 */
	bool addCloseCallback(CloseCallback closeCallback);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 15:55:05
	 * 
	 * 关闭 RTSP 链接
	 */
	void close();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 11:31:52
	 * 
	 * 获取链接 Id
	 */
	uint32_t getConnectionId();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 16:25:10
	 * 
	 * 获取 Socket Id
	 * @return socket id
	 */
	VL_SOCKET getSocketId();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-17 00:11:51
	 * 
	 * 获取写队列
	 * @return 当前 RTSP 链接写队列
	 */
	QueueThread<Buffer>* getWriteQueue();

private:
	/**
	 * +======================================================================================================================+
	 * @Author: CimZzz
	 * @Date: 2022-01-14 11:21:35
	 * 
	 * 代码分割块，以下内容涉及: 
	 * 
	 * 内部方法
	 * 
	 */

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 09:24:37
	 * 
	 * 读取线程执行回调函数
	 */
	void _onReadRun();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 16:00:36
	 * 
	 * 消息队列接收回调函数
	 * @param dataPtr 写数据指针
	 */
	void _onRecvWriteBuffer(std::shared_ptr<Buffer> buffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 11:23:27
	 * 
	 * 处理 OPTIONS 指令
	 * @param parser RTSP 解析器
	 * @param mediaSession 媒体会话
	 * @param respBuffer 响应字节缓冲区
	 */
	void _handleOPTIONS(RTSPParser& parser, std::shared_ptr<MediaSession>& mediaSession, std::shared_ptr<Buffer>& respBuffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 11:25:15
	 * 
	 * 处理 DESCRIBE 指令
	 * @param parser RTSP 解析器
	 * @param mediaSession 媒体会话
	 * @param respBuffer 响应字节缓冲区
	 */
	void _handleDESCRIBE(RTSPParser& parser, std::shared_ptr<MediaSession>& mediaSession, std::shared_ptr<Buffer>& respBuffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 11:25:28
	 * 
	 * 处理 SETUP 指令
	 * @param parser RTSP 解析器
	 * @param mediaSession 媒体会话
	 * @param respBuffer 响应字节缓冲区
	 */
	void _handleSETUP(RTSPParser& parser, std::shared_ptr<MediaSession>& mediaSession, std::shared_ptr<Buffer>& respBuffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 11:25:37
	 * 
	 * 处理 PLAY 指令
	 * @param parser RTSP 解析器
	 * @param mediaSession 媒体会话
	 * @param respBuffer 响应字节缓冲区
	 */
	void _handlePLAY(RTSPParser& parser, std::shared_ptr<MediaSession>& mediaSession, std::shared_ptr<Buffer>& respBuffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 11:25:44
	 * 
	 * 处理 TEARDOWN 指令
	 * @param parser RTSP 解析器
	 * @param mediaSession 媒体会话
	 * @param respBuffer 响应字节缓冲区
	 */
	void _handleTEARDOWN(RTSPParser& parser, std::shared_ptr<MediaSession>& mediaSession, std::shared_ptr<Buffer>& respBuffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 11:25:55
	 * 
	 * 处理 GET_PARAMETER 指令
	 * @param parser RTSP 解析器
	 * @param mediaSession 媒体会话
	 * @param respBuffer 响应字节缓冲区
	 */
	void _handleGET_PARAMETER(RTSPParser& parser, std::shared_ptr<MediaSession>& mediaSession, std::shared_ptr<Buffer>& respBuffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 11:05:45
	 * 
	 * RTSP 上下文
	 */
	RTSPContext* context;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 17:28:32
	 * 
	 * 会话 Id
	 */
	std::string sessionId;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 11:31:36
	 * 
	 * 链接 Id
	 */
	uint32_t connectionId;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 16:24:35
	 * 
	 * Socket Id
	 */
	VL_SOCKET socketId;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 16:58:30
	 * 
	 * 判断 Connection 是否已经结束
	 */
	bool isClosed;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 16:57:43
	 * 
	 * 线程锁
	 */
	std::mutex mutex;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 15:52:36
	 * 
	 * 内部套接字
	 */
	std::shared_ptr<TCPSocket> socket;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 09:32:02
	 * 
	 * 链接关闭回调函数列表
	 */
	std::vector<CloseCallback> closeCallbackVector;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 16:09:34
	 * 
	 * 媒体数据分发器列表
	 */
	std::shared_ptr<MediaDispatcher> dispatcher;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 09:23:36
	 * 
	 * 读取线程
	 */
	RunnableThread readThread;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 15:54:15
	 * 
	 * 写数据消息队列
	 */
	QueueThread<Buffer> writeQueue;
};


}


#endif //_VL_RTSP_CONNECTION__H_
